package com.asset.dispoal.file.agreementCaseData.service.commom;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.asset.dispoal.business.bsAgreement.domain.db.mapper.AgreementMapper;
import com.asset.dispoal.business.bsEvidenceRecognition.domain.db.entity.MatchSuccessEvidence;
import com.asset.dispoal.business.bsEvidenceRecognition.domain.db.entity.RemoveEvidenceContract;
import com.asset.dispoal.business.bsEvidenceRecognition.domain.db.mapper.BusinessDataManageMapper;
import com.asset.dispoal.business.bsEvidenceRecognition.domain.redis.dto.RedisIdCardDTO;
import com.asset.dispoal.business.idcardrefresh.domain.db.entity.IdCardRefresh;
import com.asset.dispoal.business.idcardrefresh.domain.db.mapper.IdCardRefreshMapper;
import com.asset.dispoal.file.agreementCaseData.domain.db.entity.FileAgreement;
import com.asset.dispoal.file.agreementCaseData.domain.db.mapper.FileAgreementMapper;
import com.asset.dispoal.file.agreementCaseData.dto.RefreshIdCardRequest;
import com.asset.dispoal.file.evidenceRecognition.domain.dto.ContractNo;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import tech.mhuang.pacebox.core.date.DateTimeUtil;
import tech.mhuang.pacebox.core.ddd.BaseCommand;
import tech.mhuang.pacebox.core.file.FileUtil;
import tech.mhuang.pacebox.core.id.BaseIdeable;
import tech.mhuang.pacebox.core.util.CollectionUtil;
import tech.mhuang.pacebox.core.util.StringUtil;
import tech.mhuang.pacebox.springboot.core.entity.RequestModel;
import tech.mhuang.pacebox.springboot.core.local.GlobalHeaderThreadLocal;
import tech.mhuang.pacebox.springboot.core.rest.SingleRestTemplate;
import tech.mhuang.pacebox.springboot.protocol.Result;
import tech.mhuang.pacebox.springboot.redis.commands.IRedisExtCommands;

import java.io.File;
import java.time.LocalDate;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@Component
@Slf4j
public class RefreshIdCardCommand implements BaseCommand<RefreshIdCardRequest, Result> {

    @Autowired
    AgreementMapper agreementMapper;

    @Autowired
    Environment environment;

    @Autowired
    BusinessDataManageMapper businessDataManageMapper;

    @Autowired
    IRedisExtCommands redisExtCommands;

    @Autowired
    RedisProperties redisProperties;

    @Autowired
    SingleRestTemplate singleRestTemplate;

    @Autowired
    FileAgreementMapper fileAgreementMapper;

    @Autowired
    IdCardRefreshMapper idCardRefreshMapper;
    @Autowired
    BaseIdeable<String> ideable;

    private IdCardRefresh initBuilder(RefreshIdCardRequest request) {
        IdCardRefresh idCardRefresh = new IdCardRefresh();
        idCardRefresh.setId(ideable.generateId());
        idCardRefresh.setSubmitTime(DateTimeUtil.currentDate());
        idCardRefresh.setCreateUser(GlobalHeaderThreadLocal.getOrException().getUserId());
        idCardRefresh.setName(request.getName());
        idCardRefresh.setType(request.getType());
        idCardRefresh.setAssetInstBatchId(request.getAssetInstBatchId());
        idCardRefresh.setSubmitTime(DateTimeUtil.currentDate());
        return idCardRefresh;

    }

    @SneakyThrows
    @Override
    public Result execute(RefreshIdCardRequest request) {
        //TODO 原告文件上传的问题
        //TODO 预览
        //TODO 调解管理
        //TODO 还款管理
        IdCardRefresh idCardRefresh = initBuilder(request);
        LocalDate now = LocalDate.now();
        String year = String.valueOf(now.getYear());
        String month = String.valueOf(now.getMonthValue());
        String day = String.valueOf(now.getDayOfMonth());
        List<String> agreementIdList = null;
        if ("2".equals(request.getType())) {
            //全部的合同
        } else {
            if ("3".equals(request.getType())) {
                //导入的合同
                List<ContractNo> contractNoList = EasyExcel.read(request.getFile().getInputStream()).head(ContractNo.class).sheet().doReadSync();
                List<String> contractNoStrList = contractNoList.stream().map(ContractNo::getContractNo).collect(Collectors.toList());
                if (CollectionUtil.isEmpty(contractNoStrList)) {
                    return Result.faild("导入的合同号不存在");
                }
                agreementIdList = agreementMapper.queryAgreementByNo(contractNoStrList, request.getAssetInstBatchId());
            }
            if (CollectionUtil.isEmpty(agreementIdList)) {
                return Result.faild("导入的合同号不存在");
            }
        }
        //1：查询所有需要匹配的数据
        List<Map<String, String>> mapList = businessDataManageMapper.queryDataDetail(request.getAssetInstBatchId());
        List<Map<String, Object>> queryResult = businessDataManageMapper.queryResult(request.getAssetInstBatchId(), mapList);
        if (CollectionUtil.isEmpty(queryResult)) {
            return Result.faild("暂无数据");
        }
        //3: 查询身份证类型种类下证据及删除的证据
        List<MatchSuccessEvidence> matchSuccessEvidenceList = businessDataManageMapper.queryMatchSuccessEvidenceByIdCard(request.getAssetInstBatchId());
        List<RemoveEvidenceContract> removeEvidenceContractList = businessDataManageMapper.queryRemoveEvidenceContractByIdCard(request.getAssetInstBatchId());
        if (CollectionUtil.isEmpty(matchSuccessEvidenceList)) {
            return Result.faild("没有种类下的对应身份证关系的证据数据");
        }

        if (CollectionUtil.isNotEmpty(agreementIdList)) {
            Set<String> agreementIdSet = new HashSet<>(agreementIdList);
            queryResult = queryResult.parallelStream().filter(query -> agreementIdSet.contains(query.get("cotractId"))).collect(Collectors.toList());
        }
        Map<Object, List<Map<String, Object>>> groupedMap = queryResult.stream().filter(e -> Objects.nonNull(e.get("caseId"))).collect(Collectors.groupingBy(e -> e.get("caseId")));
        JSONObject jsonObject = new JSONObject();
        //循环人
        for (Map.Entry<Object, List<Map<String, Object>>> entry : groupedMap.entrySet()) {
            String caseId = (String) entry.getKey();
            jsonObject.put(caseId, new JSONArray());
            List<Map<String, Object>> agreementDataList = entry.getValue();
            //循环人下的合同
            for (Map<String, Object> agreementData : agreementDataList) {
                Set<String> removeEvidenceIdSet = removeEvidenceContractList.stream()
                        .filter(removeEvidenceType -> agreementData.get("contractId").equals(removeEvidenceType.getContractId()))
                        .map(RemoveEvidenceContract::getEvidenceId)
                        .collect(Collectors.toSet());
                List<MatchSuccessEvidence> matchSuccessEvidences = matchSuccessEvidenceList;
                if (CollectionUtil.isNotEmpty(removeEvidenceIdSet)) {
                    matchSuccessEvidences = matchSuccessEvidenceList.stream().filter(evidenceType -> !removeEvidenceIdSet.contains(evidenceType.getEvidenceId())).collect(Collectors.toList());
                }
                //循环合同下的证据，如果满足条件则放入
                for (MatchSuccessEvidence matchSuccessEvidence : matchSuccessEvidences) {
                    Boolean checkEvidence = Boolean.FALSE;
                    if (StringUtil.isEmpty(matchSuccessEvidence.getAlias())) {
                        checkEvidence = Boolean.TRUE;
                    }
                    try {
                        //证据匹配上的返回成功
                        if (agreementData.get(matchSuccessEvidence.getAlias()).equals(matchSuccessEvidence.getResult())) {
                            checkEvidence = Boolean.TRUE;
                        }
                    } catch (Exception ignore) {
                    }
                    //证据存在合同则写入
                    if (checkEvidence) {
                        String fileUrl = environment.getProperty("file.evidence.url") + "/" + matchSuccessEvidence.getFileUrl();
                        jsonObject.getJSONArray(caseId).add(fileUrl);
                    }
                }
                //找到一个合同的相关身份证证据就不需要找其他合同的
                if (CollectionUtil.isNotEmpty(jsonObject.getJSONArray(caseId))) {
                    break;
                }
            }
            if (CollectionUtil.isEmpty(jsonObject.getJSONArray(caseId))) {
                //如果没有数据则删除
                jsonObject.remove(caseId);
            }
        }
        if (jsonObject.keySet().isEmpty()) {
            return Result.faild("当前数据里没有对应身份类型的证据");
        }
        if ("3".equals(request.getType())) {
            FileAgreement fileAgreement = new FileAgreement();
            fileAgreement.setId(ideable.generateId());
            fileAgreement.setFilePath(environment.getProperty("file.evidence.url") + "/custdownload/" + year + "/" + month + "/" + day + "/");
            fileAgreement.setFileName(ideable.generateId() + "_" + request.getFile().getName());
            fileAgreement.setFileOriginalName(request.getFile().getName());
            File copyFile = new File(fileAgreement.getFilePath());
            if (!copyFile.exists()) {
                FileUtil.createDirectory(copyFile, true);
            }
            request.getFile().transferTo(new File(fileAgreement.getFilePath() + fileAgreement.getFileName()));
            idCardRefresh.setFileId(fileAgreement.getId());
            fileAgreementMapper.insert(fileAgreement);
        }
        idCardRefreshMapper.insert(idCardRefresh);
        Set<String> caseList = jsonObject.keySet();
        if (CollectionUtil.isNotEmpty(caseList)) {
            idCardRefreshMapper.insertCase(idCardRefresh.getId(), caseList);
        }
        remoteCall(idCardRefresh.getId(), jsonObject);
        return Result.ok();
    }

    private void remoteCall(String id, JSONObject jsonObject) {
        redisExtCommands.hset(6, "idcard_before", id, jsonObject);
        RedisIdCardDTO dto = new RedisIdCardDTO();
        dto.setDb("6");
        dto.setId("1");
        dto.setKey(id);
        dto.setHost(redisProperties.getHost());
        dto.setPort(redisProperties.getPort());
        dto.setPasswd(redisProperties.getPassword());
        dto.setIdcardFile("idcard_before");
        dto.setErrorKey("idcard_err_key");
        dto.setNotifyKey("idcard_notify_key");
        dto.setServerUrl(environment.getProperty("evidence.idcard.notify_url"));
        RequestModel<String> requestModel = new RequestModel<String>() {
        };
        requestModel.setUrl(environment.getProperty("evidence.idcard.send_url"));
        requestModel.setMethod(HttpMethod.POST);
        requestModel.setParams(dto);
        singleRestTemplate.request(requestModel);
    }
}